/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package expertos;

import DTOs.DTOProducto;
import entidadesNegocio.Producto;
import entidadesNegocio.TipoProducto;
import excepciones.ExpertoProductosException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import persistencia.ExcepcionFachada;
import persistencia.Fachada;

/**
 *
 * @author diego
 */
public class ExpertoProductos extends Experto {

    private TipoProducto tipoProductoSeleccionado;//Se puede elegir un tipo de producto para modificarlo o eliminarlo

    public List<Producto> buscarProducto(DTOProducto dtoBusqueda) throws ExpertoProductosException {
        List<Producto> productosEncontrados = null;

        if (dtoBusqueda == null) {
            productosEncontrados = Fachada.getInstancia().buscar(Producto.class, null);
        } else {
            Criteria criterio = Fachada.getInstancia().crearCriterio(Producto.class);
            if (dtoBusqueda.getCodigo().length() > 0) {
                criterio.add(Restrictions.like("codigoProducto", "%" + dtoBusqueda.getCodigo() + "%"));
            }
            if (dtoBusqueda.getNombre().length() > 0) {
                criterio.add(Restrictions.like("nombreProducto", "%" + dtoBusqueda.getNombre() + "%").ignoreCase());
            }
            if (dtoBusqueda.getTipo().length() > 0) {
                criterio.createAlias("tipoProducto", "tipo");
                criterio.add(Restrictions.like("tipo.nombreTipoProducto", "%" + dtoBusqueda.getTipo() + "%").ignoreCase());
            }
            criterio.addOrder(Order.asc("codigoProducto"));
            productosEncontrados = Fachada.getInstancia().buscar(Producto.class, criterio);
        }

        if (productosEncontrados.isEmpty()) {
            throw new ExpertoProductosException("No se han encontrado productos para los datos ingresados");
        }

        return productosEncontrados;

    }

    public List<Producto> buscarProductosXtipo(TipoProducto tipo) {
        List<Producto> productosEncontrados = null;


        Criteria criterio = Fachada.getInstancia().crearCriterio(Producto.class);
        criterio.createAlias("tipoProducto", "tipo");
        criterio.add(Restrictions.eq("tipo.id", tipo.getId()));

        criterio.addOrder(Order.asc("codigoProducto"));
        productosEncontrados = Fachada.getInstancia().buscar(Producto.class, criterio);


        if (productosEncontrados.isEmpty()) {
            return null;
        }

        return productosEncontrados;

    }

    public TipoProducto buscarTipoxCodigo(String codigo) {
        Criteria criterio = Fachada.getInstancia().crearCriterio(TipoProducto.class);
        criterio.add(Restrictions.like("codigoTipoProducto", "%" + codigo + "%"));
        TipoProducto productoEncontrado = (TipoProducto) criterio.uniqueResult();
        return productoEncontrado;

    }

    public TipoProducto buscarTipoxNombre(String nombre) {
        Criteria criterio = Fachada.getInstancia().crearCriterio(TipoProducto.class);
        criterio.add(Restrictions.like("nombreTipoProducto", "%" + nombre + "%"));
        TipoProducto productoEncontrado = (TipoProducto) criterio.uniqueResult();
        return productoEncontrado;

    }

    public List<TipoProducto> buscarTipos() throws ExpertoProductosException {
        List<TipoProducto> tiposEncontrados = null;
        tiposEncontrados = Fachada.getInstancia().buscar(TipoProducto.class, null);

        if (tiposEncontrados.isEmpty()) {
            throw new ExpertoProductosException("No se han encontrado tipos de productos");
        }

        return tiposEncontrados;
    }

    public void crearNuevoTipoProducto(String codigo, String nombreTipo) throws ExpertoProductosException {
        if (buscarTipoxCodigo(codigo) != null) {
            throw new ExpertoProductosException("Ya existe tipo de producto con codigo: " + codigo);
        } else {
            TipoProducto nuevoTipo = new TipoProducto();
            nuevoTipo.setCodigoTipoProducto(codigo);
            nuevoTipo.setNombretipoproducto(nombreTipo);
            try {
                Fachada.getInstancia().guardar(nuevoTipo);
            } catch (ExcepcionFachada ex) {
                throw new ExpertoProductosException("ERROR al guardar objeto: " + ex.getMessage());
            }

        }
    }

    public void guardarTipoProducto(TipoProducto tipo) throws ExpertoProductosException {
        try {
            Fachada.getInstancia().guardar(tipo);
        } catch (ExcepcionFachada ex) {
            throw new ExpertoProductosException("ERROR al guardar objeto: " + ex.getMessage());
        }
    }

    public void guardarTipoProducto(List<TipoProducto> listaTipos) throws ExpertoProductosException {
        try {
            for (TipoProducto tipo : listaTipos) {
                Fachada.getInstancia().guardar(tipo);
            }
        } catch (ExcepcionFachada ex) {
            throw new ExpertoProductosException("ERROR al guardar objeto: " + ex.getMessage());
        }
    }

    public void guardarProducto(DTOProducto nuevoProdDTO) throws ExpertoProductosException {
        try {
            validarDTOProd(nuevoProdDTO);
        } catch (ExpertoProductosException ex) {
            throw ex;
        }
        try {
            buscarProducto(nuevoProdDTO);
        } catch (ExpertoProductosException ex) {
            Producto nuevoProducto = new Producto();
            nuevoProducto.setCodigoProducto(nuevoProdDTO.getCodigo());
            nuevoProducto.setNombreProducto(nuevoProdDTO.getNombre());
            nuevoProducto.setTipoProducto(buscarTipoxNombre(nuevoProdDTO.getTipo()));
            try {
                Fachada.getInstancia().guardar(nuevoProducto);
            } catch (ExcepcionFachada ex1) {
                throw new ExpertoProductosException("ERROR al guardar objeto: " + ex.getMessage());
            }
        }


    }

    private void validarDTOProd(DTOProducto nuevoProdDTO) throws ExpertoProductosException {
        if (nuevoProdDTO.getCodigo().length() == 0) {
            throw new ExpertoProductosException("Falta completar campo codigo");
        }
        if (nuevoProdDTO.getNombre().length() == 0) {
            throw new ExpertoProductosException("Falta completar campo nombre");
        }
        if (nuevoProdDTO.getCodigo().equalsIgnoreCase("Seleccione Un Tipo de Producto")) {
            throw new ExpertoProductosException("Falta seleccionar Tipo de Producto");
        }
    }

    public void eliminarTipoProducto(TipoProducto tipo) throws ExpertoProductosException {

        List<Producto> productos = buscarProductosXtipo(tipo);
        if (productos != null) {
            //TODO: ver que hacer cuando hay productos de un tipo que se quiere eliminar (Deberían eliminarse esos productos)
        }
        tipo.setEliminado(Boolean.TRUE);
        try {
            Fachada.getInstancia().guardar(tipo);
        } catch (ExcepcionFachada ex) {
            throw new ExpertoProductosException("ERROR al eliminar objeto: " + ex.getMessage());
        }
    }

    public void seleccionarTipo(TipoProducto tipo) {
        tipoProductoSeleccionado = tipo;
    }
}
